from django.test import TestCase
# python manage.py test exercise.tests.LoginTests
# python manage.py test exercise.tests.RegisterTests
# python manage.py test exercise.tests.CourseSearchTests
# Create your tests here.
from django.test import TestCase, Client
from django.urls import reverse
from .models import USER, Course, Coach, Booking, Teach
from django.contrib.auth.hashers import make_password
from django.http import HttpResponse
class LoginTests(TestCase):
    def setUp(self):
        # 创建测试用户
        self.user = USER.objects.create(
            account='testuser',
            password=make_password('testpass123'),
            name='Test User',
            gender='M',
            age=25,
            contact='123456789',
            address='Test Address'
        )
        
        # 创建测试教练
        self.coach = Coach.objects.create(
            account='testcoach',
            password='coachpass123',
            coach_name='Test Coach',
            gender='F',
            specialty = '足球',
            contact='987654321',
            income= 5000
        )
        
        self.client = Client()
    
    def test_user_login_success(self):
        """测试用户成功登录(TC-001)"""
        response = self.client.get(reverse('home'), {
            'account': 'testuser',
            'password': 'testpass123',
            'option': '用户'
        })
        #验证响应状态码是否为200（HTTP成功）
        self.assertEqual(response.status_code, 200)
        # 验证响应是否使用了'homepage.html'模板
        self.assertTemplateUsed(response, 'homepage.html')
    
    def test_coach_login_success(self):
        """测试教练成功登录(TC-002)"""
        response = self.client.get(reverse('home'), {
            'account': 'testcoach',
            'password': 'coachpass123',
            'option': '教练'
        })
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'homepage.html')
    
    def test_account_not_exist(self):
        """测试账号不存在(TC-003)"""
        response = self.client.get(reverse('user'), {
            'account': 'nonexist',
            'password': 'anypass',
            'option': '用户'
        })
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "账号不存在！")
    
    def test_wrong_password(self):
        """测试密码错误(TC-004)"""
        response = self.client.get(reverse('user'), {
            'account': 'testuser',
            'password': 'wrongpass',
            'option': '用户'
        })
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "密码错误!")
    
    def test_empty_account(self):
        """测试空账号(TC-005)"""
        response = self.client.get(reverse('user'), {
            'account': '',
            'password': 'anypass',
            'option': '用户'
        })
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "账号不存在")
    
    def test_empty_password(self):
        """测试空密码(TC-006)"""
        response = self.client.get(reverse('user'), {
            'account': 'testuser',
            'password': '',
            'option': '用户'
        })
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "密码错误")
class RegisterTests(TestCase):
    def setUp(self):
        # 创建一个已存在的测试用户
        self.existing_user = USER.objects.create(
            account='existing_user',
            password=make_password('Testpass123'),
            name='Existing User',
            gender='M',
            age=25,
            contact='12345678901',
            address='Test Address'
        )
        
        # 初始化测试客户端
        self.client = Client()
        
        # 获取验证码（模拟实际流程）
        self.captcha_response = self.client.get(reverse('captcha'))
        self.valid_captcha = self.client.session['register_captcha']

    def test_successful_registration(self):
        """TC-007: 用户正确注册"""
        response = self.client.get(reverse('register_success'), {
            'account': 'success_user',  
            'password': 'Testpass123',
            'password_again': 'Testpass123',
            'name': 'success_user',
            'gender': '女',
            'age': '25',
            'contact': '12345678901',
            'address': 'Test Address',
            'captcha': '1234'
        })
        
        # 验证重定向到登录页面
        self.assertEqual(response.status_code, 200)
        self.assertTemplateUsed(response, 'register_success.html')
        
        # 验证用户已创建
        self.assertTrue(USER.objects.filter(account='success_user').exists())

    def test_existing_account_registration(self):
        """TC-008: 账号已注册"""
        response = self.client.get(reverse('register_success'), {
            'account': 'existing_user',  # 使用已存在的账号
            'password': 'Testpass123',
            'password_again': 'Testpass123',
            'name': 'Existing User',
            'gender': '女',
            'age': '25',
            'contact': '12345678901',
            'address': 'Test Address',
            'captcha': '1234'
        })
        
        # 验证返回错误信息
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "该账号已被注册".encode('utf-8'))
    def test_password_mismatch(self):
        """TC-009: 双重密码验证错误"""
        response = self.client.get(reverse('register_success'), {
            'account': 'success_user',  
            'password': 'Testpass123',
            'password_again': 'Testpass1234',
            'name': 'success_user',
            'gender': '女',
            'age': '25',
            'contact': '12345678901',
            'address': 'Test Address',
            'captcha': '1234'
        })
        # 验证返回错误信息
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "两次输入的密码不一致".encode())

    def test_invalid_captcha(self):
        """TC-010: 验证码输入错误"""
        response = self.client.get(reverse('register_success'), {
            'account': 'success_user',  
            'password': 'Testpass123',
            'password_again': 'Testpass123',
            'name': 'success_user',
            'gender': '女',
            'age': '25',
            'contact': '12345678901',
            'address': 'Test Address',
            'captcha': '4321'
        })
        
        # 验证返回错误信息
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "验证码错误或已过期".encode())

    def test_empty_input_registration(self):
        """TC-011: 空输入注册"""
        # 测试所有必填字段为空的情况
        required_fields = ['account', 'password', 'password_again', 'name', 'gender', 'age', 'contact', 'address']
        
        for field in required_fields:
            data = {
                'account': 'success_user',  
                'password': 'Testpass123',
                'password_again': 'Testpass1234',
                'name': 'success_user',
                'gender': '女',
                'age': '25',
                'contact': '12345678901',
                'address': 'Test Address',
                'captcha': '1234'
            }
            data[field] = ''  # 将当前字段设为空
            
            response = self.client.get(reverse('register_success'), data)
            # 验证返回错误信息
            self.assertEqual(response.status_code, 200)
            string = f"请填写完整的注册信息！{field}不能为空"
            self.assertContains(response, string.encode())

class CourseSearchTests(TestCase):
    def setUp(self):
        # 创建测试用户
        self.user = USER.objects.create(
            account='testuser',
            password=make_password('testpass123'),
            name='Test User',
            gender='M',
            age=25,
            contact='123456789',
            address='Test Address'
        )
        
        # 创建测试教练
        self.coach = Coach.objects.create(
            account='testcoach',
            password='coachpass123',
            coach_name='Test Coach',
            gender='F',
            contact='987654321',
            income='7000'
        )
        
        # 创建测试课程
        self.course1 = Course.objects.create(
            course_id=11,
            course_name='瑜伽基础',
            time='2024-05-20 13:14:00.123456+08:00',
            location='A馆'
        )
        
        self.course2 = Course.objects.create(
            course_id=21,
            course_name='高级健身',
            time='2024-05-20 13:14:00.123456+08:00',
            location='B周一馆'
        )
        
        # 关联教练和课程
        Teach.objects.create(coach=self.coach, course=self.course1)
        
        self.client = Client()
    
    def test_unauthenticated_access(self):
        """测试未登录用户访问(TC-012)"""
        response = self.client.get(reverse('search_course'))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "未登录")
    
    def test_search_specific_course(self):
        """测试搜索特定课程(TC-013)"""
        # 先登录
        self.client.get(reverse('home'), {
            'account': 'testuser',
            'password': 'testpass123',
            'option': '用户'
        })
        
        response = self.client.get(reverse('search_course'), {
            'account': 'testuser',
            'password': 'testpass123',
            'option':'用户',
            'query': '瑜伽'
        })
        
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "瑜伽".encode())
        self.assertNotContains(response, "高级健身".encode())
    
    def test_empty_search(self):
        """测试空搜索(TC-014)"""
        # 先登录
        self.client.get(reverse('home'), {
            'account': 'testuser',
            'password': 'testpass123',
            'option': '用户'
        })
        
        response = self.client.get(reverse('search_course'), {
            'account': 'testuser',
            'password': 'testpass123',
            'query': ''
        })
        
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "瑜伽".encode())
        self.assertContains(response, "高级健身".encode())
    def test_enroll_course(self):
        """测试选课操作(TC-015)"""
        # 先登录
        self.client.get(reverse('home'), {
            'account': 'testuser',
            'password': 'testpass123',
            'option': '用户'
        })
        
        # 选课
        response = self.client.get(reverse('search_course'), {
            'account': 'testuser',
            'password': 'testpass123',
            '选课': '选课',
            'option':'用户',
            'course_id': 11,
            'coach_name':'testcoach'
        })
        
        self.assertEqual(response.status_code, 200)
        self.assertTrue(Booking.objects.filter(user=self.user, course=self.course1).exists())
    
    def test_cancel_course(self):
        """测试取消选课(TC-016)"""
        # 先登录
        self.client.get(reverse('home'), {
            'account': 'testuser',
            'password': 'testpass123',
            'option': '用户'
        })
        
        # 先选课
        Booking.objects.create(user=self.user, course=self.course1)
        
        # 取消选课
        response = self.client.get(reverse('search_course'), {
            'account': 'testuser',
            'password': 'testpass123',
            '取消': '取消',
            'option':'用户',
            'course_id': 11,
            'coach_name':'testcoach'
        })
        
        self.assertEqual(response.status_code, 200)
        self.assertFalse(Booking.objects.filter(user=self.user, course=self.course1).exists())
    